package com.example.forwardmessages

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import java.util.concurrent.atomic.AtomicInteger
import android.app.AlarmManager
import android.app.PendingIntent
import java.util.Calendar
import android.os.PowerManager
import android.provider.Settings

class BootReceiver : BroadcastReceiver() {
    private val TAG = "BootReceiver"
    private val handler = Handler(Looper.getMainLooper())
    private val launchAttempts = AtomicInteger(0)
    private val maxLaunchAttempts = 8  // 增加尝试次数，特别是对MIUI系统

    // MIUI系统的特殊标识
    private val MIUI_ACTION_BOOT_COMPLETED = "miui.intent.action.BOOT_COMPLETED"
    private val MIUI_ACTION_AUTO_START = "miui.intent.action.OP_AUTO_START"

    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action
        Log.d(TAG, "接收到广播: $action")
        
        // 检查是否为MIUI系统
        val isMIUI = MIUIPermissionHelper.isMIUI()
        Log.d(TAG, "当前系统是否为MIUI: $isMIUI")
        
        // 检查各种开机相关的广播
        when {
            Intent.ACTION_BOOT_COMPLETED == action -> {
                Log.d(TAG, "标准开机广播，准备启动应用")
                // 根据系统类型设置不同的启动延迟
                val delay = if (isMIUI) 10000L else 3000L // MIUI系统延迟10秒
                scheduleAppStart(context, delay)
            }
            Intent.ACTION_LOCKED_BOOT_COMPLETED == action -> {
                Log.d(TAG, "锁屏已启动广播，准备启动应用")
                val delay = if (isMIUI) 12000L else 5000L // MIUI系统延迟12秒
                scheduleAppStart(context, delay)
            }
            "android.intent.action.QUICKBOOT_POWERON" == action ||
            "com.htc.intent.action.QUICKBOOT_POWERON" == action -> {
                Log.d(TAG, "快速启动广播，准备启动应用")
                val delay = if (isMIUI) 8000L else 2000L // MIUI系统延迟8秒
                scheduleAppStart(context, delay)
            }
            // MIUI系统特有广播
            MIUI_ACTION_BOOT_COMPLETED == action || 
            "com.miui.securitycenter.permissionmanager.service.PERMISSION_GRANTED" == action ||
            "com.miui.processguard.ServiceWatcher.BROADCAST_ACTION" == action ||
            MIUI_ACTION_AUTO_START == action ||
            "com.miui.permcenter.autostart.intent.action.AUTO_START_MANAGE" == action -> {
                Log.d(TAG, "MIUI特有广播，准备启动应用")
                
                // 对MIUI系统使用特别优化的启动策略
                scheduleAppStartWithMIUISpecificStrategies(context, 5000L)
            }
            // 三星设备特有广播
            "android.intent.action.REBOOT" == action ||
            "com.samsung.android.intent.action.BOOT_COMPLETED" == action -> {
                Log.d(TAG, "三星设备广播，准备启动应用")
                scheduleAppStart(context, 3000L) // 延迟3秒启动
            }
            // 电源相关广播作为备选方案
            Intent.ACTION_POWER_CONNECTED == action ||
            Intent.ACTION_BATTERY_CHANGED == action ||
            Intent.ACTION_BATTERY_OKAY == action -> {
                Log.d(TAG, "电源相关广播，准备启动应用")
                scheduleAppStart(context, 1000L) // 延迟1秒启动
            }
            // 网络连接广播作为备选方案
            "android.net.conn.CONNECTIVITY_CHANGE" == action ||
            "android.net.wifi.STATE_CHANGE" == action -> {
                Log.d(TAG, "网络连接广播，准备启动应用")
                scheduleAppStart(context, 1500L) // 延迟1.5秒启动
            }
            // 系统用户切换广播
            Intent.ACTION_USER_UNLOCKED == action ||
            Intent.ACTION_USER_PRESENT == action -> {
                Log.d(TAG, "用户解锁广播，准备启动应用")
                scheduleAppStart(context, 2000L) // 延迟2秒启动
            }
            else -> {
                Log.d(TAG, "接收到其他广播: $action")
                // 对于其他广播，也尝试启动应用，增加MIUI系统上的启动机会
                if (isMIUI) {
                    scheduleAppStart(context, 1000L)
                }
            }
        }
    }
    
    /**
     * 为MIUI系统提供特定的启动策略
     */
    private fun scheduleAppStartWithMIUISpecificStrategies(context: Context, delayMs: Long) {
        Log.d(TAG, "执行MIUI特定的启动策略")
        
        // 立即尝试一次启动
        startAppWithMultipleStrategies(context)
        
        // 然后安排多次延迟启动，增加成功概率
        for (i in 1..3) {
            val currentDelay = delayMs * i
            handler.postDelayed({
                Log.d(TAG, "MIUI特定策略：延迟 $currentDelay 毫秒后再次尝试启动")
                startAppWithMultipleStrategies(context)
            }, currentDelay)
        }
        
        // 额外添加一个2分钟后的尝试，作为最后的保障
        handler.postDelayed({
            Log.d(TAG, "MIUI特定策略：2分钟后最后尝试一次启动")
            startAppWithMultipleStrategies(context)
            
            // 如果仍然失败，设置一个闹钟来唤醒应用
            if (launchAttempts.get() >= maxLaunchAttempts) {
                setupAlarmForWakeUp(context)
            }
        }, 120000) // 2分钟
    }
    
    /**
     * 安排应用启动，添加延迟以避免系统资源竞争
     */
    private fun scheduleAppStart(context: Context, delayMs: Long) {
        val currentAttempt = launchAttempts.incrementAndGet()
        val isMIUI = MIUIPermissionHelper.isMIUI()
        
        if (currentAttempt > maxLaunchAttempts) {
            Log.w(TAG, "已达到最大启动尝试次数 ($maxLaunchAttempts)，停止尝试")
            // 对于MIUI系统，如果尝试多次都失败，设置一个闹钟来唤醒应用
            if (isMIUI) {
                setupAlarmForWakeUp(context)
            }
            return
        }
        
        Log.d(TAG, "计划在 $delayMs 毫秒后启动应用 (第 $currentAttempt/$maxLaunchAttempts 次尝试)")
        handler.postDelayed({
            startAppWithMultipleStrategies(context)
        }, delayMs)
        
        // 智能重试机制 - 根据系统类型和尝试次数使用不同的重试间隔
        val nextDelay = if (isMIUI) {
            // MIUI系统使用更激进的重试策略
            when {
                currentAttempt == 1 -> delayMs + 5000 // 5秒后第二次尝试
                currentAttempt == 2 -> delayMs + 10000 // 10秒后第三次尝试
                currentAttempt == 3 -> delayMs + 20000 // 20秒后第四次尝试
                currentAttempt == 4 -> delayMs + 30000 // 30秒后第五次尝试
                currentAttempt == 5 -> delayMs + 40000 // 40秒后第六次尝试
                currentAttempt == 6 -> delayMs + 60000 // 60秒后第七次尝试
                currentAttempt == 7 -> delayMs + 120000 // 120秒后第八次尝试
                else -> 0
            }
        } else {
            // 非MIUI系统使用标准重试策略
            when {
                currentAttempt == 1 -> delayMs + 10000 // 10秒后第二次尝试
                currentAttempt == 2 -> delayMs + 20000 // 20秒后第三次尝试
                currentAttempt == 3 -> delayMs + 40000 // 40秒后第四次尝试
                currentAttempt == 4 -> delayMs + 60000 // 60秒后第五次尝试
                else -> 0
            }
        }
        
        if (nextDelay > 0 && currentAttempt < maxLaunchAttempts) {
            handler.postDelayed({
                scheduleAppStart(context, nextDelay)
            }, nextDelay)
        }
    }
    
    /**
     * 设置一个闹钟来唤醒应用，这是MIUI系统上的终极唤醒策略
     */
    private fun setupAlarmForWakeUp(context: Context) {
        try {
            Log.d(TAG, "设置闹钟以唤醒应用")
            
            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val alarmIntent = Intent(context, BootReceiver::class.java)
            alarmIntent.action = "com.example.forwardmessages.ALARM_WAKEUP"
            
            // 创建一个PendingIntent，使用不同的requestCode以避免与现有闹钟冲突
            val pendingIntent = PendingIntent.getBroadcast(
                context, 
                System.currentTimeMillis().toInt() and 0xffff, // 使用当前时间作为唯一标识
                alarmIntent, 
                PendingIntent.FLAG_UPDATE_CURRENT or if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
            )
            
            // 设置闹钟，在3分钟后唤醒应用
            val calendar = Calendar.getInstance()
            calendar.timeInMillis = System.currentTimeMillis()
            calendar.add(Calendar.MINUTE, 3)
            
            // 根据Android版本使用不同的设置方法
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
            } else {
                alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
            }
            
            Log.d(TAG, "闹钟设置成功，将在3分钟后唤醒应用")
        } catch (e: Exception) {
            Log.e(TAG, "设置闹钟失败: ${e.message}")
        }
    }
    
    /**
     * 使用多种策略启动应用
     */
    private fun startAppWithMultipleStrategies(context: Context) {
        val currentAttempt = launchAttempts.get()
        val isMIUI = MIUIPermissionHelper.isMIUI()
        Log.d(TAG, "执行启动策略 (第 $currentAttempt 次尝试)")
        
        // 先尝试获取电源锁，确保设备不会进入休眠
        acquireWakeLock(context)
        
        try {
            // 检查MIUI自启动权限状态
            if (isMIUI) {
                val hasAutoStartPermission = MIUIPermissionHelper.checkAutoStartPermission(context)
                Log.d(TAG, "MIUI自启动权限状态: $hasAutoStartPermission")
                
                // 如果没有自启动权限，记录警告日志
                if (!hasAutoStartPermission) {
                    Log.w(TAG, "警告: 应用未获得MIUI自启动权限，可能导致开机启动失败")
                }
            }
            
            // 策略1: 尝试在所有情况下都启动前台服务，不仅仅是MIUI系统
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(context)
            } else {
                // 低版本Android直接启动服务
                startBackgroundService(context)
            }
            
            // 策略2: 尝试直接启动MainActivity
            if (!directStartActivity(context)) {
                Log.d(TAG, "策略2失败，尝试策略3")
                // 策略3: 使用PackageManager启动
                if (!startWithPackageManager(context)) {
                    Log.d(TAG, "策略3失败，尝试策略4")
                    // 策略4: 使用不同的Intent标志组合
                    if (!startWithDifferentFlags(context)) {
                        Log.d(TAG, "策略4失败，尝试策略5")
                        // 策略5: 尝试启动一个空的Activity，只是为了唤醒应用
                        startEmptyActivity(context)
                        
                        // 对MIUI系统，增加额外的启动策略
                        if (isMIUI) {
                            Log.d(TAG, "MIUI系统，尝试额外的启动策略")
                            startMIUISpecificStrategies(context)
                        }
                    }
                }
            }
        } finally {
            // 释放电源锁
            releaseWakeLock()
        }
    }
    
    // 电源锁对象
    private var wakeLock: PowerManager.WakeLock? = null
    
    /**
     * 获取电源锁，防止设备在启动过程中进入休眠
     */
    private fun acquireWakeLock(context: Context) {
        try {
            val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
            wakeLock = powerManager.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, 
                "ForwardMessages::BootWakeLock"
            )
            wakeLock?.acquire(60 * 1000L) // 最多持有1分钟
            Log.d(TAG, "电源锁获取成功")
        } catch (e: Exception) {
            Log.e(TAG, "获取电源锁失败: ${e.message}")
        }
    }
    
    /**
     * 释放电源锁
     */
    private fun releaseWakeLock() {
        try {
            if (wakeLock != null && wakeLock!!.isHeld) {
                wakeLock?.release()
                wakeLock = null
                Log.d(TAG, "电源锁释放成功")
            }
        } catch (e: Exception) {
            Log.e(TAG, "释放电源锁失败: ${e.message}")
        }
    }
    
    /**
     * 启动后台服务（低版本Android）
     */
    private fun startBackgroundService(context: Context) {
        try {
            val serviceIntent = Intent(context, KeepAliveService::class.java)
            context.startService(serviceIntent)
            Log.d(TAG, "后台服务启动成功")
        } catch (e: Exception) {
            Log.e(TAG, "启动后台服务失败: ${e.message}")
        }
    }
    
    /**
     * MIUI系统特有的启动策略
     */
    private fun startMIUISpecificStrategies(context: Context) {
        try {
            Log.d(TAG, "尝试MIUI系统特有的启动策略")
            
            // 策略1: 尝试通过Settings启动应用
            val settingsIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
            settingsIntent.data = android.net.Uri.fromParts("package", context.packageName, null)
            settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(settingsIntent)
            Log.d(TAG, "MIUI特有策略1: 尝试通过设置页面启动应用")
            
            // 策略2: 延迟再次启动前台服务
            handler.postDelayed({
                try {
                    startForegroundService(context)
                    Log.d(TAG, "MIUI特有策略2: 延迟启动前台服务")
                } catch (e: Exception) {
                    Log.e(TAG, "MIUI特有策略2执行失败: ${e.message}")
                }
            }, 2000)
            
        } catch (e: Exception) {
            Log.e(TAG, "执行MIUI特有策略失败: ${e.message}")
        }
    }
    
    /**
     * 直接启动MainActivity
     */
    private fun directStartActivity(context: Context): Boolean {
        return try {
            val startActivityIntent = Intent(context, MainActivity::class.java)
            startActivityIntent.addFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK or 
                Intent.FLAG_ACTIVITY_CLEAR_TOP or 
                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED or
                Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
            )
            
            context.startActivity(startActivityIntent)
            Log.d(TAG, "直接启动MainActivity成功")
            true
        } catch (e: Exception) {
            Log.e(TAG, "直接启动MainActivity失败: ${e.message}")
            false
        }
    }
    
    /**
     * 使用PackageManager启动应用
     */
    private fun startWithPackageManager(context: Context): Boolean {
        return try {
            val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
            if (launchIntent != null) {
                launchIntent.addFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK or
                    Intent.FLAG_ACTIVITY_CLEAR_TASK or
                    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
                )
                context.startActivity(launchIntent)
                Log.d(TAG, "使用PackageManager启动应用成功")
                true
            } else {
                Log.e(TAG, "无法获取启动Intent")
                false
            }
        } catch (e: Exception) {
            Log.e(TAG, "使用PackageManager启动应用失败: ${e.message}")
            false
        }
    }
    
    /**
     * 使用不同的Intent标志组合启动
     */
    private fun startWithDifferentFlags(context: Context): Boolean {
        return try {
            val startActivityIntent = Intent(context, MainActivity::class.java)
            // 使用不同的标志组合
            startActivityIntent.addFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK or
                Intent.FLAG_ACTIVITY_MULTIPLE_TASK or
                Intent.FLAG_ACTIVITY_NO_HISTORY or
                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
            )
            
            context.startActivity(startActivityIntent)
            Log.d(TAG, "使用不同的Intent标志组合启动成功")
            true
        } catch (e: Exception) {
            Log.e(TAG, "使用不同的Intent标志组合启动失败: ${e.message}")
            false
        }
    }
    
    /**
     * 启动EmptyActivity，只是为了唤醒应用
     */
    private fun startEmptyActivity(context: Context) {
        try {
            // 直接启动EmptyActivity
            val intent = Intent(context, EmptyActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            
            context.startActivity(intent)
            Log.d(TAG, "启动EmptyActivity以唤醒应用")
        } catch (e: Exception) {
            Log.e(TAG, "启动EmptyActivity失败: ${e.message}")
            
            // 如果直接启动EmptyActivity失败，尝试备用方案
            try {
                val wakeUpIntent = Intent(Intent.ACTION_MAIN)
                wakeUpIntent.addCategory(Intent.CATEGORY_LAUNCHER)
                wakeUpIntent.setPackage(context.packageName)
                wakeUpIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                
                context.startActivity(wakeUpIntent)
                Log.d(TAG, "使用备用方案启动应用以唤醒进程")
            } catch (e2: Exception) {
                Log.e(TAG, "备用方案也失败: ${e2.message}")
            }
        }
    }
    
    /**
     * 启动前台服务，提高应用存活率
     */
    private fun startForegroundService(context: Context) {
        try {
            val serviceIntent = Intent(context, KeepAliveService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(serviceIntent)
                Log.d(TAG, "前台服务启动成功")
            } else {
                context.startService(serviceIntent)
                Log.d(TAG, "后台服务启动成功")
            }
        } catch (e: Exception) {
            Log.e(TAG, "启动服务失败: ${e.message}")
        }
    }
}